package edu.pku.sei.transformation.codegen;

import java.io.File;
import java.util.List;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;

import edu.pku.sei.modeler.model.core.MetaModel;
import edu.pku.sei.modeler.project.AbstractModelingProject;
import edu.pku.sei.modeler.project.ProjectRegistry;
import edu.pku.sei.transformation.editor.model.AtomicTransformation;
import edu.pku.sei.transformation.editor.model.Transformation;
import edu.pku.sei.transformation.editor.model.execution.TransformationExecution;
import edu.pku.sei.transformation.editor.model.implement.ICodegenElement;

public abstract class CodegenAdapter {
	public abstract String getLanguage();
	
	public abstract boolean canGenerate(ICodegenElement element);
	
	public boolean generateCode(ICodegenElement element) {
		return this.generateCode(element, true);
	}
	
	public boolean generateCodeifNotExist(ICodegenElement element) {
		return this.generateCode(element, false);
	}
	
	public abstract boolean generateCode(ICodegenElement element, boolean force);
	
	public boolean generateCodeToFile(ICodegenElement element, File file) {
		return generateCodeToFile(element, file.getAbsolutePath());
	}
	
	public boolean generateCodeToFile(ICodegenElement element, IFile file) {
		return generateCodeToFile(element, file.getLocation().toOSString());
	}
	
	
	public abstract boolean generateCodeToFile(ICodegenElement element, String file);
	
	protected IFile getFile(AtomicTransformation trans, String fileName, String language) throws CoreException {
		IProject proj = getProject(trans.getModel());
		if (proj == null) {
			return null;
		}
		
		IFolder transFolder = proj.getFolder("T"+trans.getElementID());
		if (!transFolder.exists()) {
				transFolder.create(true, true, null);
		}
		
		IFolder languageFolder = transFolder.getFolder(language);
		if (!languageFolder.exists()) {
				languageFolder.create(true, true, null);
		}
		
		IFile file = languageFolder.getFile(fileName);
		if (!file.exists()) {
				file.create(null, IResource.NONE, null);
		}
	
		return file;
	}

	protected IFile getFile(TransformationExecution transExe, String fileName, String language) throws CoreException {
		IProject proj =getProject(transExe.getModel());
		if (proj == null) {
			return null;
		}
		Transformation trans = transExe.getTransformation();
		if (trans == null)
			return null;
		
		IFolder transFolder = proj.getFolder("T"+trans.getElementID());
		if (!transFolder.exists()) {
				transFolder.create(true, true, null);
		}
		
		IFolder executionFolder = transFolder.getFolder("E"+transExe.getElementID());
		if (!executionFolder.exists()) {
			executionFolder.create(true, true, null);
		}
		
		IFolder languageFolder = executionFolder.getFolder(language);
		if (!languageFolder.exists()) {
				languageFolder.create(true, true, null);
		}
		
		IFile file = languageFolder.getFile(fileName);
		if (!file.exists()) {
				file.create(null, IResource.NONE, null);
		}
	
		return file;
	}

	private IProject getProject(MetaModel model) {
		IProject proj = null;
		List projs = ProjectRegistry.getDefault().getProjects();
		for (int i = 0; i < projs.size(); i++) {
			AbstractModelingProject ap = (AbstractModelingProject) projs.get(i);
			if (ap.getModel() == model) {
				proj = ap.getProject();
				return proj;
			}
		}
		return null;
	}
	
	public abstract String getFileName(ICodegenElement element);

}
